package com.demo.modules.job.utils;

import com.demo.modules.job.entity.CronModel;
import org.apache.commons.lang.StringUtils;
import org.springframework.scheduling.support.CronSequenceGenerator;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author: zsx
 * @create: 2020-05-26 11:03
 **/
public class CronUtil {
    /**
     * 方法摘要：构建Cron表达式
     *
     * @param cronModel
     * @return String
     */
    public static String createCronExpression(CronModel cronModel) {
        StringBuffer cronExp = new StringBuffer("");

        if (null == cronModel.getJobType()) {
            System.out.println("执行周期未配置");//执行周期未配置
        }
        //每隔几秒
        if (cronModel.getJobType().intValue() == 0 && null != cronModel.getSecond()) {
            cronExp.append("0/").append(cronModel.getSecond());
            cronExp.append(" ");
            cronExp.append("* ");
            cronExp.append("* ");
            cronExp.append("* ");
            cronExp.append("* ");
            cronExp.append("?");
        }
        //每隔几分钟
        if (cronModel.getJobType().intValue() == 4 && null != cronModel.getMinute()) {
            cronExp.append("0 ");
            cronExp.append("*/").append(cronModel.getMinute());
            cronExp.append(" ");
            cronExp.append("* ");
            cronExp.append("* ");
            cronExp.append("* ");
            cronExp.append("?");
        }
        if (null != cronModel.getSecond()
                && null != cronModel.getMinute()
                && null != cronModel.getHour()) {
            //秒
            cronExp.append(cronModel.getSecond()).append(" ");
            //分
            cronExp.append(cronModel.getMinute()).append(" ");
            //小时
            cronExp.append(cronModel.getHour()).append(" ");

            //每天
            if (cronModel.getJobType().intValue() == 1) {
                cronExp.append("* ");//日
                cronExp.append("* ");//月
                cronExp.append("?");//周
            }
            //按每周
            else if (cronModel.getJobType().intValue() == 3) {
                //一个月中第几天
                cronExp.append("? ");
                //月份
                cronExp.append("* ");
                //周
                cronExp.append(cronModel.getDayOfWeeks());
                /*Integer[] weeks = cronModel.getDayOfWeeks();
                for (int i = 0; i < weeks.length; i++) {
                    if (i == 0) {
                        cronExp.append(weeks[i]);
                    } else {
                        cronExp.append(",").append(weeks[i]);
                    }
                }*/
            } //按每月
            else if (cronModel.getJobType().intValue() == 2) {
                //一个月中的哪几天
                cronExp.append(cronModel.getDayOfMonths());
                /*Integer[] days = cronModel.getDayOfMonths();
                for (int i = 0; i < days.length; i++) {
                    if (i == 0) {
                        cronExp.append(days[i]);
                    } else {
                        cronExp.append(",").append(days[i]);
                    }
                }*/
                //月份
                cronExp.append(" * ");
                //周
                cronExp.append("?");
            }
        } else {
            System.out.println("时或分或秒参数未配置");//时或分或秒参数未配置
        }
        return cronExp.toString();
    }

    /**
     * 方法摘要：生成计划的详细描述
     *
     * @param cronModel
     * @return String
     */
    public static String createDescription(CronModel cronModel) {
        StringBuffer description = new StringBuffer();
        //计划执行开始时间
//      Date startTime = cronModel.getScheduleStartTime();

        if (null != cronModel.getSecond()
                && null != cronModel.getMinute()
                && null != cronModel.getHour()) {
            //按每天
            if (cronModel.getJobType().intValue() == 1) {
                description.append("每天");
                description.append(cronModel.getHour()).append("时");
                description.append(cronModel.getMinute()).append("分");
                description.append(cronModel.getSecond()).append("秒");
                description.append("执行");
            }
            //按每周
            else if (cronModel.getJobType().intValue() == 3) {
                if (StringUtils.isNotEmpty(cronModel.getDayOfWeeks())) {
                    String strs[] = cronModel.getDayOfWeeks().split(",");
                    String[] weekDays = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"};
                    List<String> weekDayList = new ArrayList<String>();
                    for (String str : strs) {
                        weekDayList.add(weekDays[Integer.parseInt(str) - 1]);
                    }
                    description.append("每周:").append(weekDayList).append(" ");
                }
                if (null != cronModel.getSecond()
                        && null != cronModel.getMinute()
                        && null != cronModel.getHour()) {
                    description.append(",");
                    description.append(cronModel.getHour()).append("时");
                    description.append(cronModel.getMinute()).append("分");
                    description.append(cronModel.getSecond()).append("秒");
                }
                description.append("执行");
            }
            //按每月
            else if (cronModel.getJobType().intValue() == 2) {
                //选择月份
                if (StringUtils.isNotEmpty(cronModel.getDayOfMonths())) {
                    String days = "(" + cronModel.getDayOfMonths() + ")号";
                    description.append("每月的").append(days).append(" ");
                }
                description.append(cronModel.getHour()).append("时");
                description.append(cronModel.getMinute()).append("分");
                description.append(cronModel.getSecond()).append("秒");
                description.append("执行");
            }

        }
        return description.toString();
    }

    /**
     * @param cron
     * @desc 计算表达式近20次时间
     */
    public static List<String> seeExcuteTime(String cron) {
        CronSequenceGenerator cronSequenceGenerator = new CronSequenceGenerator(cron);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<String> list = new ArrayList<String>(10);
        Date nextTimePoint = new Date();
        for (int i = 0; i < 10; i++) {
            // 计算下次时间点的开始时间
            nextTimePoint = cronSequenceGenerator.next(nextTimePoint);
            list.add(sdf.format(nextTimePoint));
        }
        return list;
    }

    //参考例子
    /*public static void main(String[] args) {

        List<String> list = CronUtil.seeExcuteTime("12 12 12 31 * ?");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        //执行时间：每天的12时12分12秒 start
        CronModel cronModel = new CronModel();

        cronModel.setJobType(0);//按每秒
        cronModel.setSecond(30);
        String cronExp = createCronExpression(cronModel);
        System.out.println(cronExp);

        cronModel.setJobType(4);//按每分钟
        cronModel.setMinute(8);
        String cronExpp = createCronExpression(cronModel);
        System.out.println(cronExpp);

        cronModel.setJobType(1);//按每天
        cronModel.setTime("12:12:12");

        String cropExp = createCronExpression(cronModel);
        System.out.println(cropExp + ":" + createDescription(cronModel));
        //执行时间：每天的12时12分12秒 end

        cronModel.setJobType(3);//每周的哪几天执行
        cronModel.setDayOfWeeks("1,2,3");
        cropExp = createCronExpression(cronModel);
        System.out.println(cropExp + ":" + createDescription(cronModel));

        cronModel.setJobType(2);//每月的哪几天执行
        cronModel.setDayOfMonths("31");
        cropExp = createCronExpression(cronModel);
        System.out.println(cropExp + ":" + createDescription(cronModel));
    }*/
}
